#ifndef _MCMC_REGION_DYNAMICS_H
#define _MCMC_REGION_DYNAMICS_H

#include "mcmcChangeAtomicRegion.h"
#include "mcmcMap.h"
#include "mcmcModelSupervisor.h"
#include "mcmcDiffusion.h"

///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
class ModelAndEnergy
{
public:
	ModelAndEnergy();
	~ModelAndEnergy();

	virtual void	Free(void);
	inline double	TotalEnergy(void){return pmodel->EnergyImageModel()+energy_shape;};
	virtual void	CopyFromRegion(MCMC_RegionElement *pregion);

public:
	MCMC_Model	*pmodel;
	double		energy_shape;
};

///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// abstract class of MCMC dynamic
class MCMC_Dynamic
{
public:
	// constructions & destructions
	MCMC_Dynamic(MCMC_Map &map, MCMC_FilterResp &respFilter1, MCMC_ModelSupervisor &model_supervisor, int &step);
	virtual ~MCMC_Dynamic();

	// operations
	virtual	void	Propose(void);
	virtual bool	TryAccept(void);
	virtual void	DoAction(void)		= 0;
	inline	bool	IsAccepted(void){return bAccept;};
	inline	double	LogOld(void){return log_pos1;};
	inline	double	LogNew(void){return log_pos2;};
	virtual void	ChangeMapPointer(MCMC_Map &map);

protected:
	inline MCMC_Layer_Regions*	LayerRegion(void){return pmap->LayerRegion();};
	virtual void		SetLayerPdf(RF_uniform &rf);
	int					Step(void){return *pstep;}

public:
	char		Info[4][200];	// used to display information on the status bar
	Raster<int>	mx_proposal;

protected:
	double		Gw2_dw1;		// transfer probability G(W'->dW)
	double		PW2;			// probability p(W'|I)dW'
	double		log_pos2;
	double		Gw1_dw2;		// transfer probability G(W->dW')
	double		PW1;			// probability P(W|I)dW
	double		log_pos1;
	double		rate;			// probability rate G(W'->dW)*P(W'|I)dW'/G(W->dW')p(W|I)dW
	double		AW1_dW2;		// acception probability: min(1,r);
	bool		bAccept;
	bool		bValidProposal;

	mcmcMatrix<int>			num_region_layer;

	MCMC_FilterResp		*prespFilter;
	Raster<int>			mask_before;
	MCMC_ModelSupervisor *pmodel_supervisor;
	MCMC_Map			*pmap;

private:
	int					*pstep;
};

// the dynamic of diffusion
class MCMC_Dn_Diffusion : public MCMC_Dynamic
{
public:
	// constructions & destructions
	MCMC_Dn_Diffusion(MCMC_Map &map, MCMC_FilterResp &respFilter1,
					  MCMC_Diffusion &mcmcDiffusion, MCMC_ModelSupervisor &model_supervisor,int &step);
	virtual ~MCMC_Dn_Diffusion();

	// operations
	virtual	void	Propose(void);
	virtual bool	TryAccept(void);
	virtual void	DoAction(void);

private:
	LinkList<int>	list_indexid;
	MCMC_Diffusion	*pmcmc_diffusion;

	MCMC_Layer_Regions	layer_region_buf;
};


// the dynamic of switch particel
class MCMC_Dn_Switch : public MCMC_Dynamic
{
public:
	// constructions & destructions
	MCMC_Dn_Switch(MCMC_Map &map, MCMC_FilterResp &respFilter1,
				   MCMC_ModelSupervisor &model_supervisor, int &step);
	virtual ~MCMC_Dn_Switch();
	virtual void FreeModels(void);

	// operations
	virtual bool	PrepareToSwitchModel(void);
	virtual double	ProposeRegionToSwitch(void);
	virtual double	Q_ProposeRegionToSwitch(void);
	virtual	void	Propose(void);
	virtual void	DoAction(void);

	virtual void	DoSwitch(void);
	virtual void	RecoverSwitch(void);

private:
	int				indexid_region;
	ModelAndEnergy	pmodel_old,pmodel_new;
	mcmcVector<int>		vc_order_indexid;
	mcmcVector<int>		vc_indexid;
	RF				rf_indexid;
};


class MCMC_Dn_RepartitionARegions
{
public:
	// constructions & destructions
	MCMC_Dn_RepartitionARegions(MCMC_Map &map, MCMC_FilterResp &resp_filter1,
								MCMC_ModelSupervisor &model_supervisor, mcmcMatrix<int> *partition_maps1);
	~MCMC_Dn_RepartitionARegions();

	// access
	inline	MCMC_Layer_Regions*		LayerRegion(void){return pmap->LayerRegion();};

	// operations
	virtual	void	Propose(void);


protected:
	MCMC_Map				*pmap;
	MCMC_LayerRegion_Record	repartition;
	MCMC_ModelSupervisor	*pmodel_supervisor;
	MCMC_FilterResp			*presp_filter;
	Raster<int>				p_parition_maps_edge[3];

	MCMC_Layer_Regions		layer_region_buf;
};


#endif
